home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!rs
- From: rs@uunet.UU.NET (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v10i073: IEN116 Nameserver
- Message-ID: <738@uunet.UU.NET>
- Date: 30 Jul 87 22:33:56 GMT
- Organization: UUNET Communications Services, Arlington, VA
- Lines: 603
- Approved: rs@uunet.UU.NET
-
- Submitted-by: mike@turing.unm.edu (Michael I. Bushnell)
- Posting-number: Volume 10, Issue 73
- Archive-name: ien116-server
-
- [ This provides an old-style (non-domain) nameserver; Mike says it's
- useful for Bridge terminal concentrators, but I wouldn't know. I
- once wrote something similar for the MIT PC/IP package. --r$ ]
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # Makefile
- # README
- # driver.c
- # nameserver.c
- # nameserver.8
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'Makefile'" '(333 characters)'
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- sed 's/^X//' << \SHAR_EOF > 'Makefile'
- X# Makefile for the IEN116 datagram server.
- X
- X.SUFFIXES: .c,v
- XVPATH=RCS
- X
- XCFLAGS=-g
- XNOBJECTS=nameserver.o
- XDOBJECTS=driver.o
- X
- Xall: nameserver driver
- X
- Xnameserver: $(NOBJECTS)
- X $(CC) $(CFLAGS) -o nameserver $(NOBJECTS)
- X
- Xdriver: $(DOBJECTS)
- X $(CC) $(CFLAGS) -o driver $(DOBJECTS)
- X
- X.c,v.o:
- X co -q $*.c
- X $(CC) $(CFLAGS) -c $*.c
- X rm -f $*.c
- X
- X
- SHAR_EOF
- if test 333 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 333 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'README'" '(603 characters)'
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- sed 's/^X//' << \SHAR_EOF > 'README'
- X
- XThis program implements the IEN 116 nameserver protocol. A driver is provided,
- Xbut it will ask for a machine probably not on your network, so it should be
- Xmodified. This program is of use primarily for Bridge terminal servers, many
- Xof which use this protocol in requesting machine addresses. For further
- Xinformation, see the document itself.
- X
- XTo compile, the command:
- X % make
- Xis sufficient. This will build the nameserver and the driver.
- X
- XIt is only known that this works on a 4.3BSD Vax, but it is likely that it
- Xwill function on any compatable UNIX(*) machine.
- X
- X(*) UNIX is a trademark of AT&T.
- SHAR_EOF
- if test 603 -ne "`wc -c < 'README'`"
- then
- echo shar: error transmitting "'README'" '(should have been 603 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'driver.c'" '(2605 characters)'
- if test -f 'driver.c'
- then
- echo shar: will not over-write existing file "'driver.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'driver.c'
- X#ifndef lint
- X static char *RCSid = "$Header: driver.c,v 1.5 87/06/24 15:02:38 mike Rel $";
- X#endif
- X
- X/* driver --
- X drive the IEN 116 nameserver.
- X
- X Written by Michael I. Bushnell.
- X Copyright (c) 1987 Michael I. Bushnell
- X You are hereby granted permission to use this program however you wish,
- X including copying and distribution. However, you are obligated not to sell
- X it or any part of it. Anyone who obtains this program receives the right
- X to do the same. This statement may not be removed from this program.
- X*/
- X
- X/*
- X * $Source: /u1/staff/mike/src/nameserver/RCS/driver.c,v $
- X * $Revision: 1.5 $
- X * $Date: 87/06/24 15:02:38 $
- X * $State: Rel $
- X * $Author: mike $
- X * $Locker: $
- X * $Log: driver.c,v $
- X * Revision 1.5 87/06/24 15:02:38 mike
- X * Prepared for final release. Added Copyright.
- X *
- X * Revision 1.4 87/06/19 17:00:05 mike
- X * More toying around.
- X *
- X * Revision 1.3 87/06/19 14:44:13 mike
- X * Toyed around.
- X *
- X * Revision 1.2 87/06/15 13:50:51 mike
- X * Changed the host it asks for
- X *
- X * Revision 1.1 87/06/12 13:42:29 mike
- X * Initial revision
- X *
- X */
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <stdio.h>
- X#include <netdb.h>
- X
- X#define PORT 5001
- X#define BUFLEN 256
- Xchar buf[BUFLEN];
- X
- X/* Driver for the IEN 116 nameserver */
- X
- Xmain()
- X{
- X int sock; /* Datagram socket */
- X struct sockaddr_in from; /* Where we got the reply from */
- X struct sockaddr_in server; /* Server's address */
- X struct sockaddr_in ourname; /* Our address */
- X int addrlen; /* Address length */
- X int c,i; /* Generic counters */
- X
- X
- X sock = socket(AF_INET, SOCK_DGRAM, 0);
- X if (sock < 0)
- X {
- X perror("driver: opening socket");
- X exit (1);
- X }
- X ourname.sin_family = AF_INET;
- X ourname.sin_port = 0;
- X ourname.sin_addr.s_addr = INADDR_ANY;
- X if (bind(sock, (struct sockaddr *)&ourname, sizeof(ourname)))
- X {
- X perror("driver: binding socket");
- X exit(1);
- X }
- X
- X server.sin_family = AF_INET;
- X server.sin_port = PORT;
- X server.sin_addr.s_addr = INADDR_ANY;
- X
- X/* stick in whatever machine you want here */
- X buf[0] = 1; /* Code for request */
- X buf[1] = 8; /* Length of message */
- X buf[2] = 'c';
- X buf[3] = 'h';
- X buf[4] = 'a';
- X buf[5] = 'r';
- X buf[6] = 'o';
- X buf[7] = 'n';
- X
- X if (sendto(sock, buf, 8, 0, (struct sockaddr *)&server, sizeof(server))==-1)
- X {
- X perror("driver: sending message");
- X exit(1);
- X }
- X
- X if ((c=recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *)&from, sizeof(from)))==-1)
- X {
- X perror("driver: getting message");
- X exit(1);
- X }
- X
- X for(i=0;i<c; ++i)
- X putchar(buf[i]);
- X}
- SHAR_EOF
- if test 2605 -ne "`wc -c < 'driver.c'`"
- then
- echo shar: error transmitting "'driver.c'" '(should have been 2605 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'nameserver.c'" '(9178 characters)'
- if test -f 'nameserver.c'
- then
- echo shar: will not over-write existing file "'nameserver.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'nameserver.c'
- X#ifndef lint
- X static char *RCSid = "$Header: nameserver.c,v 2.3 87/06/24 15:02:59 mike Rel $";
- X#endif
- X
- X/* nameserver --
- X Use the IEN 116 protocol to respond to nameserver requests.
- X
- X Written by Michael I. Bushnell.
- X Copyright (c) 1987 Michael I. Bushnell
- X You are hereby granted permission to use this program however you wish,
- X including copying and distribution. However, you are obligated not to sell
- X it or any part of it. Anyone who obtains this program receives the right
- X to do the same. This statement may not be removed from this program.
- X*/
- X
- X/*
- X * $Source: /u1/staff/mike/src/nameserver/RCS/nameserver.c,v $
- X * $Revision: 2.3 $
- X * $Date: 87/06/24 15:02:59 $
- X * $State: Rel $
- X * $Author: mike $
- X * $Locker: $
- X * $Log: nameserver.c,v $
- X * Revision 2.3 87/06/24 15:02:59 mike
- X * Final preparations for release. Addeed Copyright.
- X *
- X * Revision 2.2 87/06/24 14:54:29 mike
- X * de-lintified. Lint, stupidly, doesn't pick up the definition of h_errno f
- X * from libc.a. Sigh. Prepared for release.
- X *
- X * Revision 2.1 87/06/24 14:48:14 mike
- X * Better comments.
- X *
- X * Revision 2.0 87/06/23 16:55:03 mike
- X * Split it up into different functions.
- X *
- X * Revision 1.9 87/06/23 16:14:09 mike
- X * Added stuff to divorce process from shell and control terminal.
- X *
- X * Revision 1.8 87/06/19 16:59:36 mike
- X * Uses syslog instead of perror.
- X * Lots of symbolic constants.
- X *
- X * Revision 1.7 87/06/19 14:43:49 mike
- X * Fixed bug... need to initialize addrlen to sizeof(hisname).
- X *
- X * Revision 1.6 87/06/16 16:08:04 mike
- X * Changed all "sizeof (hisaddr)" to "addrlen."
- X * Still a bug...the last sendto is returning EINVAL???
- X *
- X * Revision 1.5 87/06/16 15:57:07 mike
- X * Actually...you need to return the raw bytes. So I changed it back.
- X * Also added bookoo error checking.
- X *
- X * Revision 1.4 87/06/15 13:50:22 mike
- X * Fixed bug...need to cast the argument of inet_ntoa into a struct in_addr.
- X *
- X * Revision 1.3 87/06/08 14:16:56 mike
- X * Uses a PORT number instead of system chosen default...now its 5001.
- X *
- X * Revision 1.2 87/06/08 14:10:33 mike
- X * Now it compiles.
- X *
- X * Revision 1.1 87/06/08 13:42:20 mike
- X * Initial revision
- X *
- X */
- X
- X#include <sys/file.h>
- X#include <sgtty.h>
- X
- X#include <signal.h>
- X#include <syslog.h>
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X
- X#include <stdio.h>
- X
- X/* Generic constants */
- X#define PORT 5001 /* Port for the server */
- X#define BUFLEN 256 /* Length of input buffer */
- X#define DEF_PROTO 0 /* Use default protocol */
- X#define NO_FLAGS 0 /* No flags on recvfrom/sendto */
- X
- X/* Message lengths */
- X#define RET_MSG_LEN 6 /* Length of what we add to buf */
- X#define ERR_MSG_LEN 3 /* Length of error messages */
- X
- X/* Message types from IEN 116 */
- X#define ADDR_REQ 1 /* Address Request */
- X#define ADDR_ANS 2 /* Address Request Answer */
- X#define ERR 3 /* Error */
- X
- X/* Error types from IEN 116 */
- X#define UNK_ERR 0 /* Unknown Error */
- X#define HOST_UNK 1 /* Host Unknown */
- X#define SYNT_ERR 2 /* Syntax Error */
- X
- Xchar buf[BUFLEN]; /* Input/Output buffer */
- Xextern int errno, h_errno;
- Xextern char *sys_errlist[];
- X
- Xmain()
- X{
- X int sock; /* Datagram socket */
- X struct sockaddr_in hisname; /* Address of requestor */
- X int addrlen; /* Length of his address */
- X struct hostent *hp, *gethostbyname(); /* Host inquired of */
- X char *name; /* Name of the machine requested */
- X int msglen; /* Length of the message received */
- X char *nameloc();
- X
- X setupsig(); /* Set up signal handling */
- X setuplog(); /* Set up the syslog connection */
- X divorce(); /* Divorce ourselves from terminal and shell */
- X sock = makesocket(); /* make and bind the socket */
- X
- X addrlen = sizeof(hisname);
- X
- X /* Main loop */
- X restart:
- X while (1)
- X {
- X /* Read a message */
- X msglen = recvfrom(sock, buf, BUFLEN - RET_MSG_LEN,
- X NO_FLAGS, (struct sockaddr *)&hisname, &addrlen);
- X if (msglen == -1)
- X {
- X syslog(LOG_ERR, "Error on incoming message: %s\n",
- X sys_errlist[errno]);
- X goto restart;
- X }
- X
- X /* Find the name */
- X name = nameloc(buf, BUFLEN, msglen, &hisname, addrlen, sock);
- X if ((int) name == -1)
- X goto restart;
- X
- X
- X /* Get the host entry */
- X if ((hp = gethostbyname(name))== NULL)
- X {
- X /* Send error message */
- X buf[msglen] = ERR;
- X buf[msglen+1] = ERR_MSG_LEN;
- X if (h_errno == HOST_NOT_FOUND ||
- X h_errno == TRY_AGAIN ||
- X h_errno == NO_ADDRESS)
- X buf[msglen+2] = HOST_UNK;
- X else
- X buf[msglen+2] = UNK_ERR;
- X if (sendto(sock, buf, msglen+ERR_MSG_LEN, NO_FLAGS,
- X (struct sockaddr *)&hisname, addrlen)==-1)
- X {
- X syslog(LOG_ERR, "Error sending error 3: %s\n", sys_errlist[errno]);
- X goto restart;
- X }
- X }
- X else
- X {
- X /* Send the reply */
- X buf[msglen] = ADDR_ANS;
- X buf[msglen+1] = RET_MSG_LEN;
- X buf[msglen+2] = hp->h_addr_list[0][0];
- X buf[msglen+3] = hp->h_addr_list[0][1];
- X buf[msglen+4] = hp->h_addr_list[0][2];
- X buf[msglen+5] = hp->h_addr_list[0][3];
- X
- X if (sendto(sock, buf, msglen+RET_MSG_LEN, NO_FLAGS,
- X (struct sockaddr *)&hisname, addrlen)==-1)
- X {
- X syslog(LOG_ERR, "Error sending reply: %s\n", sys_errlist[errno]);
- X goto restart;
- X }
- X }
- X }
- X}
- X
- X
- X/* setupsig -- Set all signals to be ignored. Those which cannot be ignored
- X will be left at the default. */
- Xsetupsig()
- X{
- X int i; /* Index of signals */
- X
- X for (i=0; i < NSIG; ++i)
- X (void) signal(i, SIG_IGN);
- X}
- X
- X
- X/* setuplog -- set up the syslog connection */
- Xsetuplog()
- X{
- X openlog("nameserver", LOG_PID | LOG_CONS, LOG_DAEMON);
- X}
- X
- X
- X/* divorce -- Divorce ourselves from the terminal and the shell */
- Xdivorce()
- X{
- X int term; /* Terminal filed */
- X
- X /* First the shell */
- X switch(fork())
- X {
- X case -1:
- X syslog(LOG_CRIT, "Cannot fork: %s\n", sys_errlist[errno]);
- X exit(1);
- X break;
- X case 0:
- X break;
- X default:
- X exit(0);
- X break;
- X }
- X
- X /* Now the files */
- X /* POTENTIAL BUG-- ASSUMES THAT THE TERMINAL IS ONLY OPEN ON FILEDS 0,1,2 */
- X (void) close (0);
- X (void) close (1);
- X (void) close (2);
- X /* Now the terminal */
- X if ((term = open("/dev/tty", O_RDWR, 0)) == -1)
- X {
- X syslog(LOG_CRIT, "Cannot open /dev/tty: %s\n", sys_errlist[errno]);
- X exit(1);
- X }
- X if (ioctl(term, TIOCNOTTY, (char *) 0) == -1)
- X {
- X syslog(LOG_CRIT, "Cannot divorce from control terminal: %s\n",
- X sys_errlist[errno]);
- X exit(1);
- X }
- X (void) close(term);
- X}
- X
- X
- X/* makesocket -- return the filed of a new bound socket */
- Xmakesocket()
- X{
- X int sock; /* Socket */
- X struct sockaddr_in ourname; /* Our name */
- X
- X /* create the socket */
- X sock = socket(AF_INET, SOCK_DGRAM, DEF_PROTO);
- X if (sock < 0)
- X {
- X syslog(LOG_CRIT, "Error opening socket: %s\n", sys_errlist[errno]);
- X exit(1);
- X }
- X ourname.sin_family = AF_INET;
- X ourname.sin_port = PORT;
- X ourname.sin_addr.s_addr = INADDR_ANY;
- X if (bind(sock, &ourname, sizeof(ourname)))
- X
- X {
- X syslog(LOG_CRIT, "Error binding socket: %s\n", sys_errlist[errno]);
- X exit(1);
- X }
- X return sock;
- X}
- X
- X
- X/* nameloc -- return the address of a null-terminated string which is the
- X name to be looked up. Report syntax errors to reportto through sock.
- X If an error occurs, return (char *) -1. If an error occurs, buf will be
- X changed. */
- Xchar *
- Xnameloc(buf, buflen, msglen, reportto, addrlen, sock)
- X char *buf; /* Buffer holding the request */
- X int buflen, /* Length of the buffer */
- X msglen, /* Length of the message in the buffer */
- X sock, /* Socket for error replies */
- X addrlen; /* Length of reportto */
- X struct sockaddr_in *reportto; /* Who we report errors to */
- X{
- X char *name; /* Address of the name */
- X int code; /* Type of request */
- X
- X buf[msglen] = '\0';
- X /* Check type */
- X code = buf[0];
- X if (code != ADDR_REQ)
- X if (code !=ADDR_ANS && code !=ERR)
- X {
- X /* Send error message */
- X buf[0] = ERR;
- X buf[1] = ERR_MSG_LEN;
- X buf[2] = SYNT_ERR;
- X if (sendto(sock, buf, ERR_MSG_LEN, NO_FLAGS,
- X (struct sockaddr *)&reportto, addrlen)==-1)
- X {
- X syslog(LOG_ERR, "Error sending error 0: %s\n", sys_errlist[errno]);
- X return (char *) -1;
- X }
- X }
- X else
- X return (char *) -1;
- X
- X /* Put name at the start of a null-terminated string */
- X if (buf[2]!='!')
- X name=buf+2;
- X else
- X {
- X for(name=buf+2; *name!='!'; ++name)
- X if (name-buf >= buflen)
- X {
- X /* Send error packet */
- X buf[0] = ERR;
- X buf[1] = ERR_MSG_LEN;
- X buf[2] = SYNT_ERR;
- X if (sendto(sock, buf, ERR_MSG_LEN, NO_FLAGS,
- X (struct sockaddr *)&reportto, addrlen)==-1)
- X {
- X syslog(LOG_ERR, "Error sending error 1: %s\n",
- X sys_errlist[errno]);
- X return (char *) -1;
- X }
- X }
- X for(++name; *name!='!'; ++name)
- X if (name-buf >= buflen)
- X {
- X /* Send error packet */
- X buf[0] = ERR;
- X buf[1] = ERR_MSG_LEN;
- X buf[2] = SYNT_ERR;
- X if (sendto(sock, buf, ERR_MSG_LEN, NO_FLAGS,
- X (struct sockaddr *)&reportto, addrlen)==-1)
- X {
- X syslog(LOG_ERR, "Error sending error 2: %s\n",
- X sys_errlist[errno]);
- X return (char *) -1;
- X }
- X }
- X ++name;
- X }
- X return name;
- X}
- X
- X
- X
- SHAR_EOF
- if test 9178 -ne "`wc -c < 'nameserver.c'`"
- then
- echo shar: error transmitting "'nameserver.c'" '(should have been 9178 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'nameserver.8'" '(702 characters)'
- if test -f 'nameserver.8'
- then
- echo shar: will not over-write existing file "'nameserver.8'"
- else
- sed 's/^X//' << \SHAR_EOF > 'nameserver.8'
- X.TH nameserver 8 "Local \- June 24, 1987" "M. I. Bushnell"
- X.SH NAME
- Xnameserver \- process IEN 116 requests
- X.SH SYNOPSIS
- X.B nameserver
- X.SH DESCRIPTION
- X\fBNameserver\fR processes requests for network addresses using the IEN 116
- Xprotocol.
- X.SH SEE ALSO
- XIEN 116 \- Internet Name Server (J. Postel)
- X.SH DIAGNOSTICS
- XVarious messages logged by syslog using LOG_CRIT and LOG_ERR.
- XMainly self-explanatory. Errors such as
- X.RS .5i
- XError sending error \fIn\fR: ....
- X.RE
- Xrefer to errors in the transmission of error messages back to the requestor.
- XFor explanation of the numbers, see the source.
- X.SH BUGS
- XWill not properly detach from the terminal if the terminal is opened on
- Xany descriptor other than 0, 1, or 2.
- SHAR_EOF
- if test 702 -ne "`wc -c < 'nameserver.8'`"
- then
- echo shar: error transmitting "'nameserver.8'" '(should have been 702 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
- Michael I. Bushnell
- a/k/a Bach II
- mike@turing.UNM.EDU
- ---
- Somewhere in Tenafly, New Jersey, a chiropractor is viewing
- ``Leave it to Beaver''!
- -- Zippy the Pinhead
-
- --
-
- Rich $alz "Anger is an energy"
- Cronus Project, BBN Labs rsalz@bbn.com
- Moderator, comp.sources.unix sources@uunet.uu.net
-